package com.bobi.tfca.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bobi.tfca.dao.AuditDao;
import com.bobi.tfca.model.constant.MailConstant;
import com.bobi.tfca.model.constant.RedisConstant;
import com.bobi.tfca.model.entity.AuditEntity;
import com.bobi.tfca.model.entity.GroupMemberEntity;
import com.bobi.tfca.model.entity.MemberEntity;
import com.bobi.tfca.model.entity.MemberProfileEntity;
import com.bobi.tfca.model.enums.AuditCategoryEnum;
import com.bobi.tfca.model.enums.AuditStatusEnum;
import com.bobi.tfca.model.enums.MemberStatusEnum;
import com.bobi.tfca.model.enums.SubAuditItemTypeEnum;
import com.bobi.tfca.model.vo.AuditVO;
import com.bobi.tfca.service.AuditService;
import com.bobi.tfca.service.GroupMemberService;
import com.bobi.tfca.service.MemberProfileService;
import com.bobi.tfca.service.MemberService;
import com.bobi.tfca.utils.MailUtil;
import com.bobi.tfca.utils.PasswordUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 审核服务层实现
 * <p>会员审核：itemId存的是会员id</p>
 * @author 李文发
 * @date 2024/4/3
 */
@Service
@Slf4j
public class AuditServiceImpl extends ServiceImpl<AuditDao, AuditEntity> implements AuditService {

    @Autowired
    private MemberService memberService;
    @Autowired
    private MemberProfileService memberProfileService;
    @Autowired
    private MailUtil mailUtil;

    @Override
    public List<AuditVO> findAllEntryApply() {
        // 查询所有会员种类
        LambdaQueryWrapper<AuditEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AuditEntity::getCategory, AuditCategoryEnum.MEMBER_APPLY.getCode())
                .eq(AuditEntity::getSubType, SubAuditItemTypeEnum.REGISTER_APPLY.getCode())
                .orderByDesc(AuditEntity::getApplyTime);
        List<AuditEntity> entityList = this.list(queryWrapper);
        List<AuditVO> auditVOList = entityList.stream().map(this::entityFill2VO).toList();

        return auditVOList;
    }

    @NotNull
    private AuditVO entityFill2VO(AuditEntity it) {
        // 转换为vo
        AuditVO auditVO = AuditVO.ofAuditEntity(it);
        // 如果已经审核后过了，设置审核人姓名
        if (AuditStatusEnum.NOT_AUDITED.getCode() != it.getAuditStatus()) {
            // 查询审核人名称
            MemberEntity auditor = memberService.getById(it.getAuditorId());
            auditVO.setAuditorName(auditor.getMemberName());
        }
        // 设置申请人姓名
        MemberEntity member = memberService.getById(it.getItemId());
        auditVO.setItemName(member.getMemberName());
        return auditVO;
    }

    @Override
    public List<AuditVO> findAllExitApply() {
        // 查询所有会员种类
        LambdaQueryWrapper<AuditEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AuditEntity::getCategory, AuditCategoryEnum.MEMBER_APPLY.getCode())
                .eq(AuditEntity::getSubType, SubAuditItemTypeEnum.QUIT_ASS_APPLY.getCode())
                .orderByDesc(AuditEntity::getApplyTime);
        List<AuditEntity> entityList = this.list(queryWrapper);
        List<AuditVO> auditVOList = entityList.stream().map(this::entityFill2VO).toList();

        return auditVOList;
    }

    @Override
    public Boolean passAudit(Integer auditId, MemberEntity member) {
        AuditEntity auditEntity = this.getById(auditId);
        if (auditEntity == null) {
            return false;
        }
        // 改变审核状态
        auditEntity.setAuditStatus(AuditStatusEnum.PASS.getCode());
        // 设置审核人
        auditEntity.setAuditorId(member.getMemberId());
        // 更新
        this.updateById(auditEntity);

        // 根据审核类型更改对应内容
        if (AuditCategoryEnum.MEMBER_APPLY.getCode().equals(auditEntity.getCategory())) {
            // 如果是会员审核
            if (SubAuditItemTypeEnum.REGISTER_APPLY.getCode().equals(auditEntity.getSubType())) {
                //  如果是注册会员，修改状态为在会，设置入会时间，生成密码，发送电子邮件，将密码发送给用户
                passRegisterApply(auditEntity.getItemId());
            } else {
                // 如果是退出会员，注销用户为离会状态，设置离会时间，删除用户所在的群，删除redis的token，发送电子邮件
                passQuitAssApply(auditEntity.getItemId());
            }
        }
        return true;
    }

    private void passQuitAssApply(Integer memberId) {
        memberService.removeAssMember(memberId);
    }

    private void passRegisterApply(Integer memberId) {
        // 修改会员状态为在会，生成密码
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setMemberId(memberId);
        memberEntity.setMemberStatus(MemberStatusEnum.NORMAL.getCode());

        String password = PasswordUtil.randomPassword(8);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String newEncode = encoder.encode(password);
        memberEntity.setPassword(newEncode);
        memberService.updateById(memberEntity);

        // 会员档案设置入会时间
        boolean update = memberProfileService.update(new LambdaUpdateWrapper<MemberProfileEntity>()
                .eq(MemberProfileEntity::getMemberId, memberId)
                .set(MemberProfileEntity::getEntryDate, LocalDate.now()));
        // 发送电子邮件，将密码发送给用户
        // 接收人信息
        MemberEntity member = memberService.getById(memberId);
        String email = member.getEmail();
        String memberName = member.getMemberName();
        String mailText = String.format(MailConstant.ENTRY_PASS_MAIL, memberName, password);
        mailUtil.sendSimpleTextMail(email, MailConstant.DEFAULT_MAIL_SUBJECT, mailText, null);
    }

    /**
     * 拒绝后审核状态不变，还应发送电子邮件
     * @param auditId
     * @param member
     * @return
     */
    @Override
    public Boolean refuseAudit(Integer auditId, MemberEntity member) {
        AuditEntity auditEntity = this.getById(auditId);
        if (auditEntity == null) {
            return false;
        }
        // 改变审核状态
        auditEntity.setAuditStatus(AuditStatusEnum.REJECT.getCode());
        // 设置审核人
        auditEntity.setAuditorId(member.getMemberId());
        // 更新
        this.updateById(auditEntity);

        MemberEntity memberEntity = memberService.getById(member.getMemberId());
        memberEntity.setTelephone(null);
        memberService.updateById(memberEntity);

        String email = memberEntity.getEmail();
        String memberName = memberEntity.getMemberName();
        // 发送电子邮件
        // 获得审核种类
        SubAuditItemTypeEnum auditType = SubAuditItemTypeEnum.getAuditType(auditEntity.getSubType());
        String mailText = String.format(MailConstant.REFUSE_APPLY_MAIL, memberName, auditType.getDesc());
        mailUtil.sendSimpleTextMail(email, MailConstant.DEFAULT_MAIL_SUBJECT, mailText, null);
        return true;
    }

    @Override
    public Boolean applyQuitAss(String leaveWords, MemberEntity member) {
        // 退会申请
        AuditEntity audit = new AuditEntity();
        audit.setApplyTime(LocalDateTime.now());
        audit.setItemId(member.getMemberId());
        audit.setCategory(AuditCategoryEnum.MEMBER_APPLY.getCode());
        audit.setSubType(SubAuditItemTypeEnum.QUIT_ASS_APPLY.getCode());
        audit.setAuditStatus(AuditStatusEnum.NOT_AUDITED.getCode());
        this.save(audit);

        // 保存留言
        member.setLeaveWords(leaveWords);
        memberService.updateById(member);
        return true;
    }
}
